package com.icongyou.enterprise.talent_marking.controller;

import com.icongyou.enterprise.common.result.Result;
import com.icongyou.enterprise.talent_marking.entity.dto.MarkPotential;
import com.icongyou.enterprise.talent_marking.entity.vo.HighPotentialSubmissions;
import com.icongyou.enterprise.talent_marking.entity.vo.SubmissionInfo;
import com.icongyou.enterprise.talent_marking.service.HighPotentialSubmissionService;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.*;

@ExtendWith(MockitoExtension.class)
@DisplayName("高潜力成果控制器测试")
class HighPotentialSubmissionConrollerTest {

    @Mock
    private HighPotentialSubmissionService highPotentialSubmissionService;

    @InjectMocks
    private HighPotentialSubmissionConroller controller;

    private MarkPotential markPotential;
    private String userId;

    @BeforeEach
    void setUp() {
        userId = "USER001";
        markPotential = new MarkPotential();
        markPotential.setUserId(userId);
        markPotential.setStudentId("STUDENT001");
        markPotential.setSubmissionId("SUBMISSION001");
        markPotential.setRemark("优秀作品");
    }

    // ==================== markHighPotential 测试 ====================

    @Test
    @DisplayName("标记高潜力成果 - 成功")
    void testMarkHighPotential_Success() {
        // Arrange
        HighPotentialSubmissions mark = new HighPotentialSubmissions();
        mark.setId("MARK001");
        Result<HighPotentialSubmissions> serviceResult = Result.success(mark);
        when(highPotentialSubmissionService.markHighPotential(any(MarkPotential.class)))
                .thenReturn(serviceResult);

        // Act
        Result result = controller.markHighPotential(markPotential);

        // Assert
        assertEquals(200, result.getCode());
        assertNotNull(result.getData());
        verify(highPotentialSubmissionService).markHighPotential(markPotential);
    }

    @Test
    @DisplayName("标记高潜力成果 - 服务层返回错误")
    void testMarkHighPotential_ServiceError() {
        // Arrange
        Result errorResult = Result.error(401, "该成果已被标记为高潜力");
        when(highPotentialSubmissionService.markHighPotential(any(MarkPotential.class)))
                .thenReturn(errorResult);

        // Act
        Result result = controller.markHighPotential(markPotential);

        // Assert
        assertEquals(401, result.getCode());
        assertEquals("该成果已被标记为高潜力", result.getMessage());
        verify(highPotentialSubmissionService).markHighPotential(markPotential);
    }

    // ==================== updateRemark 测试 ====================

    @Test
    @DisplayName("更新备注 - 成功")
    void testUpdateRemark_Success() {
        // Arrange
        HighPotentialSubmissions updatedMark = new HighPotentialSubmissions();
        updatedMark.setRemark("新备注");
        Result<HighPotentialSubmissions> serviceResult = Result.success(updatedMark);
        when(highPotentialSubmissionService.updateRemark(any(MarkPotential.class)))
                .thenReturn(serviceResult);

        // Act
        Result result = controller.updateRemark(markPotential);

        // Assert
        assertEquals(200, result.getCode());
        assertNotNull(result.getData());
        verify(highPotentialSubmissionService).updateRemark(markPotential);
    }

    @Test
    @DisplayName("更新备注 - 标记不存在")
    void testUpdateRemark_MarkNotFound() {
        // Arrange
        Result errorResult = Result.error(401, "未找到对应的高潜力标记记录");
        when(highPotentialSubmissionService.updateRemark(any(MarkPotential.class)))
                .thenReturn(errorResult);

        // Act
        Result result = controller.updateRemark(markPotential);

        // Assert
        assertEquals(401, result.getCode());
        assertEquals("未找到对应的高潜力标记记录", result.getMessage());
        verify(highPotentialSubmissionService).updateRemark(markPotential);
    }

    // ==================== unmarkHighPotential 测试 ====================

    @Test
    @DisplayName("取消标记 - 成功")
    void testUnmarkHighPotential_Success() {
        // Arrange
        Result successResult = Result.success();
        when(highPotentialSubmissionService.unmarkHighPotential(any(MarkPotential.class)))
                .thenReturn(successResult);

        // Act
        Result result = controller.unmarkHighPotential(markPotential);

        // Assert
        assertEquals(200, result.getCode());
        verify(highPotentialSubmissionService).unmarkHighPotential(markPotential);
    }

    // ==================== getMyPotentialMarks 测试 ====================

    @Test
    @DisplayName("获取我的标记列表 - 有数据")
    void testGetMyPotentialMarks_WithData() {
        // Arrange
        HighPotentialSubmissions mark1 = new HighPotentialSubmissions();
        mark1.setId("MARK001");

        HighPotentialSubmissions mark2 = new HighPotentialSubmissions();
        mark2.setId("MARK002");

        List<HighPotentialSubmissions> marks = Arrays.asList(mark1, mark2);
        Result<List<HighPotentialSubmissions>> serviceResult = Result.success(marks);
        when(highPotentialSubmissionService.getMyPotentialMarks(userId)).thenReturn(serviceResult);

        // Act
        Result result = controller.getMyPotentialMarks(userId);

        // Assert
        assertEquals(200, result.getCode());
        assertNotNull(result.getData());
        @SuppressWarnings("unchecked")
        List<HighPotentialSubmissions> resultList = (List<HighPotentialSubmissions>) result.getData();
        assertEquals(2, resultList.size());
        verify(highPotentialSubmissionService).getMyPotentialMarks(userId);
    }

    @Test
    @DisplayName("获取我的标记列表 - 空列表")
    void testGetMyPotentialMarks_EmptyList() {
        // Arrange
        Result serviceResult = Result.success("暂无高潜力成果标记", Collections.emptyList());
        when(highPotentialSubmissionService.getMyPotentialMarks(userId)).thenReturn(serviceResult);

        // Act
        Result result = controller.getMyPotentialMarks(userId);

        // Assert
        assertEquals(200, result.getCode());
        assertEquals("暂无高潜力成果标记", result.getMessage());
        verify(highPotentialSubmissionService).getMyPotentialMarks(userId);
    }

    // ==================== getHighPotentialSubmissionInfo 测试 ====================

    @Test
    @DisplayName("获取高潜力成果信息 - 有数据")
    void testGetHighPotentialSubmissionInfo_WithData() {
        // Arrange
        SubmissionInfo info1 = new SubmissionInfo();
        info1.setSubmissionId("SUB001");

        SubmissionInfo info2 = new SubmissionInfo();
        info2.setSubmissionId("SUB002");

        List<SubmissionInfo> infos = Arrays.asList(info1, info2);
        Result<List<SubmissionInfo>> serviceResult = Result.success(infos);
        when(highPotentialSubmissionService.getHighPotentialSubmissionInfo(userId))
                .thenReturn(serviceResult);

        // Act
        Result<List<SubmissionInfo>> result = controller.getHighPotentialSubmissionInfo(userId);

        // Assert
        assertEquals(200, result.getCode());
        assertNotNull(result.getData());
        assertEquals(2, result.getData().size());
        verify(highPotentialSubmissionService).getHighPotentialSubmissionInfo(userId);
    }

    @Test
    @DisplayName("获取高潜力成果信息 - 空列表")
    void testGetHighPotentialSubmissionInfo_EmptyList() {
        // Arrange
        Result<List<SubmissionInfo>> serviceResult = Result.success("暂无高潜力成果", Collections.emptyList());
        when(highPotentialSubmissionService.getHighPotentialSubmissionInfo(userId))
                .thenReturn(serviceResult);

        // Act
        Result<List<SubmissionInfo>> result = controller.getHighPotentialSubmissionInfo(userId);

        // Assert
        assertEquals(200, result.getCode());
        assertEquals("暂无高潜力成果", result.getMessage());
        verify(highPotentialSubmissionService).getHighPotentialSubmissionInfo(userId);
    }

    // ==================== 参数验证测试 ====================

    @Test
    @DisplayName("标记高潜力成果 - 传递完整的MarkPotential对象")
    void testMarkHighPotential_WithCompleteMarkPotential() {
        // Arrange
        MarkPotential completeMark = new MarkPotential();
        completeMark.setUserId("USER001");
        completeMark.setStudentId("STUDENT001");
        completeMark.setSubmissionId("SUBMISSION001");
        completeMark.setRemark("测试备注");

        Result successResult = Result.success();
        when(highPotentialSubmissionService.markHighPotential(any(MarkPotential.class)))
                .thenReturn(successResult);

        // Act
        Result result = controller.markHighPotential(completeMark);

        // Assert
        assertEquals(200, result.getCode());
        verify(highPotentialSubmissionService).markHighPotential(completeMark);
    }

    @Test
    @DisplayName("更新备注 - 传递新备注")
    void testUpdateRemark_WithNewRemark() {
        // Arrange
        MarkPotential updateRequest = new MarkPotential();
        updateRequest.setUserId(userId);
        updateRequest.setSubmissionId("SUBMISSION001");
        updateRequest.setRemark("更新后的备注");

        Result successResult = Result.success();
        when(highPotentialSubmissionService.updateRemark(any(MarkPotential.class)))
                .thenReturn(successResult);

        // Act
        Result result = controller.updateRemark(updateRequest);

        // Assert
        assertEquals(200, result.getCode());
        verify(highPotentialSubmissionService).updateRemark(updateRequest);
    }

    @Test
    @DisplayName("获取标记列表 - 不同用户ID")
    void testGetMyPotentialMarks_DifferentUsers() {
        // Arrange
        String user1 = "USER001";
        String user2 = "USER002";

        Result result1 = Result.success(Arrays.asList(new HighPotentialSubmissions()));
        Result result2 = Result.success(Collections.emptyList());

        when(highPotentialSubmissionService.getMyPotentialMarks(user1)).thenReturn(result1);
        when(highPotentialSubmissionService.getMyPotentialMarks(user2)).thenReturn(result2);

        // Act
        Result resultUser1 = controller.getMyPotentialMarks(user1);
        Result resultUser2 = controller.getMyPotentialMarks(user2);

        // Assert
        assertEquals(200, resultUser1.getCode());
        assertEquals(200, resultUser2.getCode());
        
        @SuppressWarnings("unchecked")
        List<HighPotentialSubmissions> list1 = (List<HighPotentialSubmissions>) resultUser1.getData();
        @SuppressWarnings("unchecked")
        List<HighPotentialSubmissions> list2 = (List<HighPotentialSubmissions>) resultUser2.getData();
        
        assertEquals(1, list1.size());
        assertEquals(0, list2.size());

        verify(highPotentialSubmissionService).getMyPotentialMarks(user1);
        verify(highPotentialSubmissionService).getMyPotentialMarks(user2);
    }
}
